package javafoundation.notes;

import org.jetbrains.annotations.NotNull;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.util.Date;
import java.util.TimeZone;

import static java.lang.System.*;


/**
 * @ClassName 时间
 * @Description 时间相关操作
 * @Author dzf
 * @Date 2022/7/11 17:31
 * @Version 1.0
 */
public class TimeTypeOperate {
    public static void main(String[] args) {
        
        /*
          时间格式
          yyyyMMdd
          yyyyMMddHHmmss
          yyyy-MM-dd
          yyyy-MM-dd HH:mm:ss
         */
        String pattern = "yyyy-MM-dd HH:mm:ss";
        String pattern2 = "yyyy-MM-dd HH:mm:ss.SSS";

        // SimpleDateFormat 获取时间
        String systemTime = getSystemTime(pattern);
        // currentTimeMillis() 获取时间
        getSystemTime2();
        // LocalDateTime 获取时间
        getSystemTime3(pattern2);

        // 比较时间大小
        compareTimeSizes(systemTime, systemTime);

        // Date类型获取时间差
        getTimeDiffer("2024-10-30 10:00:00");

        // 两LocalDate类型计算整数年
        getYear(LocalDate.of(2000,12,22));

    }

    /**
     *
     * @Description 根据SimpleDateFormat类型 获取系统时间
     * @Author dzf
     * @Date 2024/10/29 15:04
     * @Params [pattern 时间格式]
     * @return java.lang.String 系统时间
     * @Version 1.0
     **/
    public static @NotNull String getSystemTime(String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        String date = sdf.format(new Date());
        out.println("SimpleDateFormat获取系统时间：" + date);
        return  date;
    }

    /**
     *
     * @Description 根据currentTimeMillis() 获取系统时间
     * @Author dzf
     * @Date 2024/10/30 10:55
     * @Params [timeMS]
     * @Version 1.0
     **/
    public static void getSystemTime2() {
        //获取当前系统的时间，单位为毫秒
        long timeMS = currentTimeMillis();
        out.println("总毫秒：" +timeMS);
        DateFormat dateFormatterChina = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,DateFormat.MEDIUM);//格式化输出
        TimeZone timeZoneChina = TimeZone.getTimeZone("Asia/Shanghai");//获取时区 这句加上，很关键。
        dateFormatterChina.setTimeZone(timeZoneChina);//设置系统时区
        String time = dateFormatterChina.format(timeMS);
        out.println("上海时区系统时间：" + time);
    }

    /**
     *
     * @Description 根据LocalDateTime类型 获取系统时间
     * @Author dzf
     * @Date 2024/11/5 14:36
     * @Params [pattern 时间格式]
     * @Version 1.0
     **/
    public static void getSystemTime3 (String pattern) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern(pattern);

        // 当前时间
        LocalDateTime localDateTime = LocalDateTime.now();
        out.println("localDateTime当前时间：" + df.format(localDateTime));

        // 获取年时间
        int yearly = localDateTime.getYear();
        // 获取月时间
        int monthly = localDateTime.getMonthValue();
        // 获取日时间
        int day = localDateTime.getDayOfMonth();
        // 获取小时时间
        int hour = localDateTime.getHour();
        // 获取分钟时间
        int minute = localDateTime.getMinute();
        // 获取秒时间
        int second = localDateTime.getSecond();
        // 获取毫秒时间
        long milliseconds = localDateTime.get(ChronoField.MILLI_OF_SECOND);
        // 获取微妙时间
        long microseconds = localDateTime.get(ChronoField.MICRO_OF_SECOND);
        // 获取纳秒时间
        int nano = localDateTime.getNano();

        // 直接获取 英文版的星期几
        DayOfWeek dayOfWeek = localDateTime.getDayOfWeek();
        out.println("星期的英文名：" + dayOfWeek);

        // 转换为星期的中文名
        String week = getWeek(dayOfWeek);
        out.println("星期的中文名：" + week);

        // localDateTime 转换为 LocalDate
        LocalDate localDate = localDateTime.toLocalDate();

        int lengthOfYear = localDate.lengthOfYear();
        out.println("本年一共有 " + lengthOfYear + "天");

        int lengthOfMonth = localDate.lengthOfMonth();
        out.println("本月一共有 " + lengthOfMonth + "天");

        // localDateTime 是线程安全的，个人认为 localDateTime只能精确到毫秒
        out.println(yearly + "年 " +  monthly+ "月 " + day+ "号 "
                + dayOfWeek + "(" + week + ") " +
                + hour + "时 " + minute+ "分 " + second + "秒 "
                + milliseconds + "毫秒 " + microseconds + "微秒 " + nano + "纳秒");
    }

    /**
     *
     * @Description 比较时间大小
     * @Author dzf
     * @Date 2024/10/29 14:53
     * @Params [date1 比较时间1, date2 比较时间2]
     * @Version 1.0
     **/
    public static void compareTimeSizes(@NotNull String date1, String date2) {

        int i = date1.compareTo(date2);
        out.print("比较时间大小：");
        if (i > 0) {
            out.println(date1 + " > " + date2);
        } else if (i < 0) {
            out.println(date1 + " < " + date2);
        } else {
            out.println(date1 + " = " + date2);
        }
    }

    /**
     *
     * @Description Date类型计算时间差
     * @Author dzf
     * @Date 2024/10/30 14:44
     * @Params [otherTime]
     * @Version 1.0
     **/
    public static void getTimeDiffer(String otherTime) {
        Date date = new Date();//当前时间
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date time = new Date();
        try {
            time = sf.parse(otherTime);
        } catch (ParseException e) {
            out.println(e.getMessage());
        }
        // 当前时间与其他时间相差的毫秒数
        long diff = date.getTime() - time.getTime();
        long sec = diff / 1000;
        long min = diff / 60 / 1000;
        long hours = diff / 60 / 60 / 1000;
        out.println("相差多少秒：" + sec);
        out.println("相差多少分钟：" + min);
        out.println("相差多少小时：" + hours);
    }

    /**
     *
     * @Description 两LocalDate类型计算时间差
     * 可计算年龄，工龄等
     * @Author dzf
     * @Date 2024/11/4 14:41
     * @Params [date 距今日期]
     * @Version 1.0
     **/
    public static void getYear (LocalDate date) {
        //传过来的日期
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy");
        String dateStr = df.format(date);
        Long yearLong = Long.parseLong(dateStr);

        //当前日期
        LocalDate yearNow = LocalDate.now();
        String yearNowStr = df.format(yearNow);
        Long yearNowLong = Long.parseLong(yearNowStr);

        //当前 - 传过来的参数
        long age = yearNowLong - yearLong;
        int intExact = Math.toIntExact(age);
        out.println("计算两个日期整数年的差：" + intExact + "年");
    }

    /**
     *
     * @Description 转换为星期的中文名
     * @Author dzf
     * @Date 2024/11/5 10:09
     * @Params [dayOfWeek 英文星期几]
     * @return week 星期的中文名
     * @Version 1.0
     **/
    public static String getWeek (@NotNull DayOfWeek dayOfWeek) {
        int weekValue = dayOfWeek.getValue();
        String[] weekDays = {"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"};
        return weekDays[weekValue-1];
    }
}
